package javaNIO1.buffer;


import java.nio.BufferUnderflowException;
import java.nio.CharBuffer;

/**
 * Created with Intel IDEA.
 * 批量移动 :  get() 把数据从缓冲区中移动到数组中
 *            put() 把数组中的数据移动到缓冲区
 * @Auther: gjt
 * @Date: 2024/7/5 21:18
 */
public class batchRemove {
    private static CharBuffer charBuffer = CharBuffer.allocate(100);
    private static CharBuffer smartCharBuffer = CharBuffer.allocate(3);
    private static CharBuffer blankCharBuffer = CharBuffer.allocate(3);

    public static void main(String[] args) {
        charBuffer.put('a');
        charBuffer.put('b');
        charBuffer.put('c');
        charBuffer.put('d');
        smartCharBuffer.put('d');
        smartCharBuffer.put('e');
        smartCharBuffer.put('f');
        charBuffer.position(0);
        smartCharBuffer.position(0);
//        param(charBuffer, smartCharBuffer);

        push(blankCharBuffer);
    }

    /**
     * 将数据批量移动到缓冲区中：
     * （1):将数组直接作为参数放入缓冲区
     * （2）:使用offset 和 length 参数指定目标数组的子区间
     * note：批量移动总是具有长度的;调用get() 函数 缓冲区的位置属性总是向前移动
     * 如果将一个小缓冲区中填入一个大数组，将会抛出BufferUnderflowException 并且缓冲区的状态保持不变,必须至指定缓冲区中剩余的数据的长度;
     * 如果数组小于 缓冲区的大小 会抛出数组下标越界
     */
    private static void param(CharBuffer charBuffer, CharBuffer smartCharBuffer) {
        char[] origin = new char[100];
        char[] originData = new char[8];
        System.out.println(charBuffer.position() + "位置；" + charBuffer.limit() + "上界；" + charBuffer.capacity());


//       try{
//           charBuffer.get(origin);
//       }catch (BufferUnderflowException e){
//           e.printStackTrace();
//       }
//        // 这两个操作是等价的
//        charBuffer.get(origin,0,origin.length);

        //
        int remaining = charBuffer.remaining();
        charBuffer.mark().position();
        charBuffer.get(origin, 0, remaining);

        for (char c : origin) {
            System.out.println(c);
        }
        charBuffer.reset();
        System.out.println(charBuffer.position() + "位置；" + charBuffer.limit() + "上界；" + charBuffer.capacity());
        System.out.println(charBuffer.remaining() + "剩余元素个数");
//        try{
//            charBuffer.get(originData);
//        }catch (Exception e){
//            e.printStackTrace();
//        }

//        System.out.println(charBuffer.position() + "位置；" + charBuffer.limit() + "上界；" + charBuffer.capacity());

        // 不能直接放大数组
        try {
            smartCharBuffer.get(originData);
        } catch (BufferUnderflowException e) {
            e.printStackTrace();
        }
        // 将另一个缓冲区的放入此缓冲区中 传递数据时会传递两个缓冲区的数据
        // 两个缓冲的位置都会前进所传递的数据元素的数量 如果charBuffer的remaining 小于 smartCharBuffer的remaining 则会抛出BufferOverflowException
        if(charBuffer.remaining() < smartCharBuffer.remaining()){
            return;
        }else {
            charBuffer.put(smartCharBuffer);
        }
        System.out.println(charBuffer.position() + "位置；" + charBuffer.limit() + "上界；" + charBuffer.capacity());
        System.out.println(smartCharBuffer.position() + "位置；" + smartCharBuffer.limit() + "上界；" + smartCharBuffer.capacity());
        while (charBuffer.hasRemaining()) {
            System.out.println(charBuffer.get());
        }

    }


    /**
     *  put:将数组中的数据复制到缓冲中 如果数组的长度大于缓冲区剩余元素个数 抛出BufferOverflowException
     *  参数是数组时  put(data,1,2) 就是数组索引的1-2 的位置包含1-2
     *  参数是字符串  put(data1,1,8) 就是字符串索引 1-7 的位置包含 1-7
     * @param charBuffer
     */
    private static void push(CharBuffer charBuffer){
        char [] data = {'a','b','c'};
        String data1 = "abcd";
        System.out.println(charBuffer.position() + "位置；" + charBuffer.limit() + "上界；" + charBuffer.capacity());
        charBuffer.put(data1,1,2); // 等价于 charBuffer.put(data1, 0 , data1.length)

        System.out.println(charBuffer.position() + "位置；" + charBuffer.limit() + "上界；" + charBuffer.capacity());
        charBuffer.flip(); // 翻转 position为0 limit 为元素末尾
        while(charBuffer.hasRemaining()){
            System.out.println(charBuffer.get());
        }

    }


}
